/**
 * 连线配置工具类
 */
export class EdgeConfig {
  /**
   * 获取连线配置
   * @param {Object} source 源节点
   * @param {Object} target 目标节点
   * @param {string} type 连线类型
   */
  static getEdgeConfig(source, target, type = 'normal') {
    const baseConfig = {
      source: { cell: source, port: 'out' },
      target: { cell: target, port: 'in' },
      attrs: {
        line: {
          stroke: '#5F95FF',
          strokeWidth: 2,
          targetMarker: {
            name: 'block',
            width: 12,
            height: 8,
          },
        },
      },
    }

    const typeConfigs = {
      normal: {
        // 直线，使用默认配置
      },
      smooth: {
        router: {
          name: 'er',
          args: {
            direction: 'H',
          },
        },
        connector: {
          name: 'smooth',
          args: {
            radius: 8,
          },
        },
      },
      step: {
        router: {
          name: 'manhattan',
          args: {
            padding: 1,
          },
        },
        connector: {
          name: 'rounded',
          args: {
            radius: 8,
          },
        },
      },
    }

    return { ...baseConfig, ...typeConfigs[type] }
  }

  /**
   * 获取连线中间点位置
   * @param {Object} edge 连线对象
   */
  static getEdgeCenter(edge) {
    try {
      // 获取连线的路径点
      const vertices = edge.getVertices()
      console.log('连线路径点:', vertices)
      
      // 获取连线的实际路径数据（使用正确的方法）
      let path = null
      try {
        // 尝试获取连线的路径属性
        path = edge.attr('line/path')
        if (!path) {
          // 如果没有path属性，尝试获取其他路径相关信息
          const line = edge.getAttrs().line
          if (line && line.path) {
            path = line.path
          }
        }
        
        // 如果还是没有，尝试获取连线的其他属性
        if (!path) {
          const attrs = edge.getAttrs()
          console.log('连线属性:', attrs)
          // 尝试从其他可能的属性中获取路径信息
          if (attrs.line && attrs.line.d) {
            path = attrs.line.d // SVG路径的d属性
          }
        }
        
        console.log('连线路径数据:', path)
      } catch (error) {
        console.warn('无法获取连线路径数据:', error)
      }
      
      if (vertices && vertices.length > 0) {
        // 对于有多个路径点的情况，使用更智能的中点计算
        if (vertices.length === 1) {
          // 只有一个路径点，直接使用
          const midPoint = vertices[0]
          console.log('使用单个路径点计算中心:', midPoint)
          return {
            x: midPoint.x,
            y: midPoint.y
          }
        } else if (vertices.length > 1) {
          // 多个路径点，计算几何中心
          let totalX = 0
          let totalY = 0
          vertices.forEach(vertex => {
            totalX += vertex.x
            totalY += vertex.y
          })
          const center = {
            x: totalX / vertices.length,
            y: totalY / vertices.length
          }
          console.log('使用多个路径点计算几何中心:', center)
          return center
        }
      }
      
      // 如果路径点不足，尝试使用连线的实际路径
      if (path && path.length > 0) {
        try {
          // 尝试解析路径数据，X6中的路径可能是SVG路径格式
          if (typeof path === 'string') {
            // 解析SVG路径字符串（支持path和d属性）
            let pathSegments = path.match(/[ML]\s*([^ML]+)/g)
            if (!pathSegments) {
              // 尝试解析SVG的d属性格式
              pathSegments = path.match(/[ML]\s*([^ML]+)/g)
            }
            
            if (pathSegments && pathSegments.length >= 2) {
              // 取路径的中间段
              const midIndex = Math.floor(pathSegments.length / 2)
              const midSegment = pathSegments[midIndex]
              const coords = midSegment.replace(/^[ML]\s*/, '').trim().split(/\s+/)
              if (coords.length >= 2) {
                const center = {
                  x: parseFloat(coords[0]),
                  y: parseFloat(coords[1])
                }
                console.log('使用SVG路径段计算中心:', center)
                return center
              }
            }
          } else if (Array.isArray(path)) {
            // 如果路径是数组格式
            if (path.length >= 2) {
              const midIndex = Math.floor(path.length / 2)
              const midPoint = path[midIndex]
              if (midPoint && typeof midPoint.x === 'number' && typeof midPoint.y === 'number') {
                console.log('使用路径数组计算中心:', midPoint)
                return midPoint
              }
            }
          }
        } catch (pathError) {
          console.warn('解析路径失败:', pathError)
        }
      }
      
      // 备选方案：使用连线边界框的中心
      const edgeBBox = edge.getBBox()
      if (edgeBBox && edgeBBox.width > 0 && edgeBBox.height > 0) {
        const center = {
          x: edgeBBox.x + edgeBBox.width / 2,
          y: edgeBBox.y + edgeBBox.height / 2
        }
        console.log('使用边界框计算中心:', center)
        
        // 如果边界框中心看起来合理，直接返回
        if (edgeBBox.width < 1000 && edgeBBox.height < 1000) {
          return center
        }
      }
      
      // 最后备选：使用源节点和目标节点的中点，但考虑组边界
      const sourceCell = edge.getSourceCell()
      const targetCell = edge.getTargetCell()
      
      if (sourceCell && targetCell) {
        const sourceBBox = sourceCell.getBBox()
        const targetBBox = targetCell.getBBox()
        
        // 计算源节点和目标节点的中心点
        const sourceCenter = {
          x: sourceBBox.x + sourceBBox.width / 2,
          y: sourceBBox.y + sourceBBox.height / 2
        }
        
        const targetCenter = {
          x: targetBBox.x + targetBBox.width / 2,
          y: targetBBox.y + targetBBox.height / 2
        }
        
        // 检查是否跨越组边界
        const sourceParent = sourceCell.getParent()
        const targetParent = targetCell.getParent()
        const isCrossGroup = (sourceParent && sourceParent.isNode()) !== (targetParent && targetParent.isNode())
        
        if (isCrossGroup) {
          // 跨越组边界时，使用更智能的位置计算
          const dx = targetCenter.x - sourceCenter.x
          const dy = targetCenter.y - sourceCenter.y
          const distance = Math.sqrt(dx * dx + dy * dy)
          
          if (distance > 0) {
            // 确定哪个节点在组内，哪个在组外
            const sourceInGroup = sourceParent && sourceParent.isNode()
            const targetInGroup = targetParent && targetParent.isNode()
            
            let adjustmentFactor = 0.2 // 默认调整因子
            
            if (sourceInGroup && !targetInGroup) {
              // 源节点在组内，目标节点在组外，+号偏向组外
              adjustmentFactor = 0.3
            } else if (!sourceInGroup && targetInGroup) {
              // 源节点在组外，目标节点在组内，+号偏向组外
              adjustmentFactor = -0.3
            }
            
            const adjustedCenter = {
              x: sourceCenter.x + dx * (0.5 + adjustmentFactor),
              y: sourceCenter.y + dy * (0.5 + adjustmentFactor)
            }
            console.log('跨越组边界，调整中心位置:', adjustedCenter, '调整因子:', adjustmentFactor)
            return adjustedCenter
          }
        }
        
        // 返回两个中心点的中点
        const center = {
          x: (sourceCenter.x + targetCenter.x) / 2,
          y: (sourceCenter.y + targetCenter.y) / 2
        }
        
        console.log('使用节点中心计算中心:', center, '源节点中心:', sourceCenter, '目标节点中心:', targetCenter)
        return center
      }
      
      // 最后备选：使用连线边界框的中心
      if (edgeBBox) {
        const center = {
          x: edgeBBox.x + edgeBBox.width / 2,
          y: edgeBBox.y + edgeBBox.height / 2
        }
        console.log('使用边界框计算中心:', center)
        return center
      }
      
      return null
    } catch (error) {
      console.error('获取连线中间位置失败:', error)
      return null
    }
  }

  /**
   * 在连线中间插入节点
   * @param {Object} edge 连线对象
   * @param {Object} newNode 新节点
   * @param {Object} graphManager 图形管理器
   */
  static insertNodeInEdge(edge, newNode, graphManager, sourceId = null, targetId = null) {
    try {
      
      
      // 检查edge对象是否有效
      if (!edge) {
        console.error('edge对象为空')
        return null
      }
      
      if (!edge.isEdge || !edge.isEdge()) {
        console.error('edge对象不是有效的连线对象')
        return null
      }
      
      let source, target
      
      // 如果提供了sourceId和targetId，优先使用它们
      if (sourceId && targetId) {
        source = graphManager.graph.getCellById(sourceId)
        target = graphManager.graph.getCellById(targetId)

      } else {
        // 否则尝试从连线对象获取
        source = edge.getSourceCell()
        target = edge.getTargetCell()
        
      }
      
      if (!source || !target) {
        console.error('无法获取连线的源节点或目标节点')
        console.error('source:', source)
        console.error('target:', target)
        return null
      }
      
      // 保存源节点和目标节点的ID，以防连线删除后无法访问
      const finalSourceId = source.id
      const finalTargetId = target.id
      
      // 删除原连线
      edge.remove()
      
      // 重新获取节点对象（以防连线删除后节点引用失效）
      const sourceNode = graphManager.graph.getCellById(finalSourceId)
      const targetNode = graphManager.graph.getCellById(finalTargetId)
      
      if (!sourceNode || !targetNode) {
        console.error('删除连线后无法重新获取源节点或目标节点')
        return null
      }
      
      // 使用EdgeConfig创建新连线配置
      const edgeConfig1 = EdgeConfig.getEdgeConfig(sourceNode, newNode, 'normal')
      const edgeConfig2 = EdgeConfig.getEdgeConfig(newNode, targetNode, 'normal')
      
      // 添加新连线：源节点 -> 新节点
      const edge1 = graphManager.addEdge(edgeConfig1)
      
      // 添加新连线：新节点 -> 目标节点
      const edge2 = graphManager.addEdge(edgeConfig2)
      
      // 为新连线添加加号图标，延迟添加确保连线路径已经计算完成
      setTimeout(() => {
        if (edge1) {
          graphManager.addPlusIconToEdge(edge1)
        }
        if (edge2) {
          graphManager.addPlusIconToEdge(edge2)
        }
      }, 200)
      
      // 使用简单的推开算法，避免完全重新布局
      setTimeout(() => {
        EdgeConfig.adjustNodesAroundNewNode(newNode, sourceNode, targetNode, graphManager)
      }, 300)
      
      return { edge1, edge2 }
    } catch (error) {
      console.error('插入节点到连线失败:', error)
      return null
    }
  }

  /**
   * 调整新节点周围的节点位置
   * @param {Object} newNode 新插入的节点
   * @param {Object} source 源节点
   * @param {Object} target 目标节点
   * @param {Object} graphManager 图形管理器
   */
  static adjustNodesAroundNewNode(newNode, source, target, graphManager) {
    try {
      const graph = graphManager.graph
      const allNodes = graph.getNodes()
      
      // 只调整与新节点重叠的节点，避免过度推开
      allNodes.forEach(node => {
        if (node === newNode || node === source || node === target) {
          return // 跳过新节点、源节点和目标节点
        }
        
        const nodeBBox = node.getBBox()
        const newNodeBBox = newNode.getBBox()
        
        // 检查是否重叠
        const overlapX = !(nodeBBox.x + nodeBBox.width < newNodeBBox.x || newNodeBBox.x + newNodeBBox.width < nodeBBox.x)
        const overlapY = !(nodeBBox.y + nodeBBox.height < newNodeBBox.y || newNodeBBox.y + newNodeBBox.height < nodeBBox.y)
        
        if (overlapX && overlapY) {
          // 有重叠，需要推开
          const nodeCenter = {
            x: nodeBBox.x + nodeBBox.width / 2,
            y: nodeBBox.y + nodeBBox.height / 2
          }
          
          const newNodeCenter = {
            x: newNodeBBox.x + newNodeBBox.width / 2,
            y: newNodeBBox.y + newNodeBBox.height / 2
          }
          
          // 计算推开方向
          const dx = nodeCenter.x - newNodeCenter.x
          const dy = nodeCenter.y - newNodeCenter.y
          
          if (dx !== 0 || dy !== 0) {
            // 标准化方向向量
            const length = Math.sqrt(dx * dx + dy * dy)
            const unitX = dx / length
            const unitY = dy / length
            
            // 温和的推开距离，避免过度推开
            const pushDistance = 120
            
            // 计算新位置
            const newX = nodeBBox.x + unitX * pushDistance
            const newY = nodeBBox.y + unitY * pushDistance
            

            
            // 应用新位置
            node.position(newX, newY)
          }
        }
      })
      

      
    } catch (error) {
      console.error('调整节点位置失败:', error)
    }
  }
} 